package editStudentGui;

import group.SystemGroup;
import group.UserGroup;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;

import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;

import role.Role;
import seminar.Seminar;
import student.Student;

@SuppressWarnings("serial")
public class EditStudentTableModel extends AbstractTableModel implements
		TableModel
{
	private ArrayList<EditStudentTableContent> tableContents = new ArrayList<EditStudentTableContent>();

	public EditStudentTableModel()
	{
		fill();
	}

	/**
	 * Füllt die Tabelle mit allen Studenten, die vorhanden sind
	 */
	private void fill()
	{
		tableContents.clear();
		SystemGroup systemgr = Seminar.getSystemgroup();
		for (int i = 0; i < systemgr.getMembers().size(); i++)
		{
			tableContents.add(new EditStudentTableContent(systemgr,
					new role.Role(), systemgr.getMembers().get(i)));
			System.out.println(i);
		}

		Iterator<UserGroup> iter_grup = Seminar.getUsergoups().iterator();
		while (iter_grup.hasNext())
		{
			UserGroup userGr = iter_grup.next();
			for (int i = 0; i < userGr.getRoles().size(); i++)
			{
				if (userGr.getRoles().get(i).hasStudent())
				{
					tableContents.add(new EditStudentTableContent(userGr,
							userGr.getRoles().get(i), userGr.getRoles().get(i)
									.getStudent()));
				}
			}
		}
	}

	private String[] columnNames = new String[] { "", "", "Vorname",
			"Nachname", "MatrNr.", "Fachber.", "e-mail", "Rolle", "Gruppe" };

	@Override
	public int getColumnCount()
	{
		return 9;
	}

	@Override
	public Class<?> getColumnClass(int columnIndex)
	{
		if (columnIndex <= 1)
		{
			return Boolean.class;
		}
		return super.getColumnClass(columnIndex);
	}

	@Override
	public int getRowCount()
	{
		return tableContents.size();
	}

	@Override
	public String getColumnName(int column)
	{
		return columnNames[column];
	}

	@Override
	public boolean isCellEditable(int rowIndex, int columnIndex)
	{
		if (columnIndex < 7)
			return true;
		return false; // Gruppen und Rollen hier nicht editerbar
	}

	@Override
	public Object getValueAt(int rowIndex, int columnIndex)
	{
		return tableContents.get(rowIndex).getValue(columnIndex);

	}

	/**
	 * Falls ein Wert editiert wurde, setzt diese Funktion den Wert auch im
	 * Content-Modell, auch überprüft sie, dass jeweils nur eine Checkbox
	 * ausgewählt ist.
	 */
	@Override
	public void setValueAt(Object aValue, int rowIndex, int columnIndex)
	{
		if (columnIndex <= 1)// Für Checkboxen
		{
			Iterator<EditStudentTableContent> it = tableContents.iterator();
			if (columnIndex == 0)
			{
				while (it.hasNext())
				{
					it.next().setFirstChoose(false);
				}
			} else
			{
				while (it.hasNext())
				{
					it.next().setSecondChoose(false);
				}
			}
		}
		EditStudentTableContent temp = tableContents.get(rowIndex);
		temp.setValue(columnIndex, aValue);
		tableContents.set(rowIndex, temp);
		if (columnIndex < 2) // Es haben sich wahrscheinlich viele Checkboxes
								// geändert
			super.fireTableDataChanged();
		else
			// Es hat sich nur die eine Zelle geändert
			super.fireTableCellUpdated(rowIndex, columnIndex);
	}

	public void update()
	{
		this.fill();
		super.fireTableDataChanged();

	}

	public void delete(int index)
	{

		Seminar.removeStudent(tableContents.get(index).getStudent());
		tableContents.remove(index);
		super.fireTableRowsDeleted(index, index);
	}

	/**
	 * Vertauscht die jeweils angewählten Studenten
	 */
	public void trade()
	{
		EditStudentTableContent tc0;
		EditStudentTableContent tc1;
		Student s0, s1;
		int choose0 = this.numberOfChoose(0);
		int choose1 = this.numberOfChoose(1);
		tc0 = tableContents.get(choose0);
		tc1 = tableContents.get(choose1);
		s0 = tc0.getStudent();
		s1 = tc1.getStudent();
		if (tc0.getGroup().getClass() == SystemGroup.class
				&& tc1.getGroup().getClass() == SystemGroup.class)
		{
			SystemGroup g0 = (SystemGroup) tc0.getGroup();
			SystemGroup g1 = (SystemGroup) tc1.getGroup();
			g0.addStudent(s1);
			g1.addStudent(s0);
			g0.removeStudent(s0);
			g1.removeStudent(s1);
		} else if (tc0.getGroup().getClass() == SystemGroup.class
				&& tc1.getGroup().getClass() == UserGroup.class)
		{
			SystemGroup g0 = (SystemGroup) tc0.getGroup();
			Role r1 = tc1.getRole();
			g0.addStudent(s1);
			r1.setStudent(s0);
			g0.removeStudent(s0);
		} else if (tc0.getGroup().getClass() == UserGroup.class
				&& tc1.getGroup().getClass() == SystemGroup.class)
		{
			Role r0 = tc0.getRole();
			SystemGroup g1 = (SystemGroup) tc1.getGroup();
			r0.setStudent(s1);
			g1.addStudent(s0);
			g1.removeStudent(s1);
		} else if (tc0.getGroup().getClass() == UserGroup.class
				&& tc1.getGroup().getClass() == UserGroup.class)
		{
			Role r0 = tc0.getRole();
			Role r1 = tc1.getRole();
			r0.setStudent(s1);
			r1.setStudent(s0);
		}
		super.fireTableDataChanged();
		// super.fireTableRowsUpdated(choose0, choose0);
		// super.fireTableRowsUpdated(choose1, choose1);
	}

	/**
	 * Gibt die Nummer der Zeile zurück, bei der die Checkbox ausgewählt ist
	 * bzw. -1 wenn nichts ausgewählt ist
	 * 
	 * @param choose
	 *            : Nummer der Spalte (1. oder 2. Checkbox-Spalte)
	 * @return Nummer der gecheckten Zeile
	 */
	public int numberOfChoose(int choose)
	{
		ListIterator<EditStudentTableContent> it = tableContents.listIterator();
		if (choose == 0)
		{
			while (it.hasNext())
			{
				if (it.next().getFirstChoose() == true)
					return it.previousIndex();
			}
		}
		if (choose == 1)
		{
			while (it.hasNext())
			{
				if (it.next().getSecondChoose() == true)
					return it.previousIndex();
			}
		}
		return -1;
	}

}